package com.xfcycle.zebrabikegp.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.util.Log;

import com.xfcycle.zebrabikegp.listener.ObtainBitmapByWebListener;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Bitmap 图片处理相关工具类
 * Created by xFcycle on 2017/5/9.
 */
public class BitmapUtil {

    private final static String TAG = "BitmapUtil";
    private ObtainBitmapByWebListener obtainBitmapByWebListener;

    /**
     * 将byte数组转化为Bitmap图片输出
     *
     * @param bytePicture 需要转化的byte数组
     * @return 转化完成的Bitmap图片
     */
    public static Bitmap byte2Bitmap(byte[] bytePicture) {
        Bitmap picture = BitmapFactory.decodeByteArray(bytePicture, 0, bytePicture.length);
        return null;
    }

    /**
     * 将Bitmap图片转化为byte数组
     *
     * @param bitmap 需要转化的Bitmap图片
     * @return 转化后得到的byte数组
     */
    public static byte[] bitmap2Byte(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] bitmapByte = baos.toByteArray();
        return bitmapByte;
    }

    /**
     * 通过网络路径获取图片并将其缓存到手机中
     * @param webPath 网络路径
     * @param filePath 缓存路径
     * @return
     */
    public void obtainBitmapByWeb(final String webPath, final String filePath){

        new Thread(new Runnable() {
            @Override
            public void run() {
                Bitmap bitmap = null;
                InputStream is = null;
                try {
                    URL realUrl = new URL(webPath);
                    //获取和Url之间的连接
                    HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();

                    //建立实际的连接
                    connection.connect();

                    //判断返回码获得相应的is流
                    int responseCode = connection.getResponseCode();
                    if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_ACCEPTED || responseCode == HttpURLConnection.HTTP_CREATED) {
                        is = connection.getInputStream();
                        bitmap = BitmapFactory.decodeStream(is);
                        //存储到手机中
                        savePictureToFile(filePath, bitmap);
                    } else {
                        Log.e(TAG, "obtainBitmapByWeb: ------------------- 获取图片失败");
                    }
                    //关闭网络连接
                    connection.disconnect();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (null != is) {
                            is.close();
                        }
                    } catch (Exception e2) {
                        e2.printStackTrace();
                    }
                }
                obtainBitmapByWebListener.ObtainBitmapByWebFinish(bitmap);
            }
        }).start();
    }

    /**
     * 利用图片String路径获取Bitmap对象 获得按比例压缩后的图片，并存储到指定路径
     *
     * @param picturePath  需要压缩的图片路径
     * @param targetHeight 预期压缩高度
     * @param targetWidth  预期压缩宽度
     * @param targetPath   指定存储路径
     * @return
     */
    public static Bitmap compressBitmapByPath(String picturePath, int targetHeight, int targetWidth, String targetPath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        //只将图片头信息读取到内存中
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(picturePath, options);

        //获取图片原始大小
        int height = options.outHeight;
        int width = options.outWidth;

        //设置缩放比例
        options.inSampleSize = getCompressRatio(height,width,targetHeight,targetWidth);
        options.inJustDecodeBounds = false;
        Bitmap resultBitmap = BitmapFactory.decodeFile(picturePath, options);

        //保存图片到指定位置
        savePictureToFile(targetPath, resultBitmap);

        return resultBitmap;
    }

    /**
     * 利用存在手机中的Uri地址获取Bitmap对象 按比例压缩图片，并存储到指定路径
     *
     * @param bitmapUri    需要压缩的图片路径
     * @param targetHeight 预期压缩高度
     * @param targetWidth  预期压缩宽度
     * @param targetPath   指定存储路径
     * @return
     */
    public static Bitmap compressBitmapByUri(Uri bitmapUri, int targetHeight, int targetWidth, String targetPath, Context context) {

        InputStream bitmapIs = null;

        //获取Bitmap输出流
        try {
            bitmapIs = context.getContentResolver().openInputStream(bitmapUri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Log.e(TAG, "compressBitmapByPath: ----------------无法通过Uri获取Bitmap输出流");
        }

        BitmapFactory.Options options = new BitmapFactory.Options();
        //只将图片头信息读取到内存中
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(bitmapIs,null,options);

        //获取图片原始大小
        int height = options.outHeight;
        int width = options.outWidth;

        //设置缩放比例
        options.inSampleSize = getCompressRatio(height,width,targetHeight,targetWidth);
        options.inJustDecodeBounds = false;
        Bitmap resultBitmap = null;
        try {
            resultBitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(bitmapUri), null, options);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //保存图片到指定位置
        savePictureToFile(targetPath, resultBitmap);

        //关闭流
        if (null != bitmapIs) {
            try {
                bitmapIs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultBitmap;
    }


    /**
     * 获得当前Bitmap缩放倍率
     *
     * @param bitmapHeight 当前Bitmap高度
     * @param bitmapWidth  当前Bitmap宽度
     * @param targetHeight 预期Bitmap高度
     * @param targetWidth  预期Bitmap宽度
     * @return 获得计算好的缩小倍率
     */
    private static int getCompressRatio(int bitmapHeight, int bitmapWidth, int targetHeight, int targetWidth) {

        //设置缩放倍率，1表示无缩放，数字越大得到的图片越小
        int compressRatio = -1;

        //以宽高中较大的为基准计算缩放比例
        if (bitmapHeight > targetHeight && bitmapHeight > bitmapWidth) {
            compressRatio = Math.round(bitmapHeight / targetHeight);
        }

        if (bitmapWidth > targetWidth && bitmapWidth > bitmapHeight) {
            compressRatio = Math.round(bitmapWidth / targetWidth);
        }

        if (1 > compressRatio) {
            compressRatio = 1;
        }

        return compressRatio;
    }

    /**
     * 保存图片到指定路径
     *
     * @param targetPath 指定的文件路径
     * @param bitmap     需要保存的图片
     */
    public static void savePictureToFile(String targetPath, Bitmap bitmap) {
        File compressPicture = new File(targetPath);

        //若同名文件已存在，则删除
        if (compressPicture.exists()) {
            compressPicture.delete();
        }

        FileOutputStream fos = null;
        try {
            //创建图片文件
            compressPicture.createNewFile();
            fos = new FileOutputStream(compressPicture);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "compressBitmap: 创建压缩后图片文件失败");
        } finally {
            try {
                if (null != fos) {
                    fos.flush();
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 判断图片是否存在
     * @param filePath 图片地址
     * @return 判断的布尔值
     */
    public static boolean judgeBitmapExit(String filePath){
        File compressPicture = new File(filePath);
        if(compressPicture.exists()){
            return true;
        }
        return false;
    }

    /**
     * 设置从网络获取图片完成 监听
     * @param obtainBitmapByWebListener 自定义回调函数
     */
    public void setOnObtainBitmapByWebListener(ObtainBitmapByWebListener obtainBitmapByWebListener){
        this.obtainBitmapByWebListener = obtainBitmapByWebListener;
    }

}
